<?php

namespace app\common\model;
use think\model\concern\SoftDelete;
use think\Db;
/**
 * 子订单表
 * Class OrderSub
 * @package app\common\model
 */
class OrderSub extends Common
{
    use SoftDelete;
    protected $deleteTime = 'isdel';
    protected $autoWriteTimestamp = true;
    protected $createTime = 'ctime';
    protected $updateTime = 'utime';

    const ORDER_STATUS_NORMAL = 1;          //订单状态正常
    const ORDER_STATUS_COMPLETE = 2;        //订单状态完成
    const ORDER_STATUS_CANCEL = 3;          //订单状态取消

    const PAY_STATUS_NO = 1;                //未付款
    const PAY_STATUS_YES = 2;               //已付款
    const PAY_STATUS_PARTIAL_YES = 3;       //部分付款
    const PAY_STATUS_PARTIAL_NO = 4;        //部分退款
    const PAY_STATUS_REFUNDED = 5;          //已退款

    const SHIP_STATUS_NO = 1;               //未发货
    const SHIP_STATUS_PARTIAL_YES = 2;      //部分发货
    const SHIP_STATUS_YES = 3;              //已发货
    const SHIP_STATUS_PARTIAL_NO = 4;       //部分退货
    const SHIP_STATUS_RETURNED = 5;         //已退货

    const RECEIPT_NOT_CONFIRMED = 1;        //未确认收货
    const CONFIRM_RECEIPT = 2;              //确认收货

    const NO_COMMENT = 1;                   //没有评价
    const ALREADY_COMMENT = 2;              //已经评价

    const ALL_PENDING_PAYMENT = 1;          //总订单类型 待付款
    const ALL_PENDING_DELIVERY = 2;         //待发货
    const ALL_PARTIAL_DELIVERY = 8;         //部分发货
    const ALL_PENDING_RECEIPT = 3;          //待收货
    const ALL_PENDING_EVALUATE = 4;         //待评价
    const ALL_COMPLETED_EVALUATE = 5;       //已评价
    const ALL_COMPLETED = 6;                //已完成
    const ALL_CANCEL = 7;                   //已取消

    const ORDER_TYPE_COMMON = 1;            //订单类型，1普通订单，严格按照cart模型里的type_common字段来设置，是一一对应的
    const ORDER_TYPE_PINTUAN = 2;           //订单类型，2拼团订单


    /**
     * 订单明细表关联
     * @return \think\model\relation\HasMany
     */
    public function items()
    {
        return $this->hasMany('OrderItems','sub_order_id', 'id');
    }
    /**
     * 店铺表关联
     * @return \think\model\relation\HasOne
     */
    public function shop()
    {
        return $this->hasOne('Shop','id', 'shop_id');
    }
    /**
     * 主订单表关联
     * @return \think\model\relation\HasOne
     */
    public function orders()
    {
        return $this->hasOne('Order','order_id', 'order_id');
    }

    /**
     * 订单的用户信息关联
     * @return \think\model\relation\HasOne
     */
    public function user()
    {
        return $this->hasOne('User', 'id', 'user_id');
    }

    /**
     * 售后关联
     * @return \think\model\relation\HasMany
     */
    public function aftersales()
    {
        return $this->hasMany('BillAftersales', 'sub_order_id', 'id');
    }

    /**
     * 售后单关联
     * @return \think\model\relation\HasMany
     */
    public function aftersalesItem()
    {
        return $this->hasMany('BillAftersales', 'sub_order_id', 'id');
    }

    /**
     * 支付单关联
     * @return \think\model\relation\HasMany
     */
    public function paymentRelItem()
    {
        return $this->hasMany('BillPaymentsRel', 'source_id', 'id');
    }

    /**
     * 退款单关联
     * @return \think\model\relation\HasMany
     */
    public function refundItem()
    {
        return $this->hasMany('BillRefund', 'source_id', 'id');
    }

    /**
     * 提货单关联
     * @return \think\model\relation\HasMany
     */
    public function ladingItem()
    {
        return $this->hasMany('BillLading', 'sub_order_id', 'id');
    }

    /**
     * 退货单关联
     * @return \think\model\relation\HasMany
     */
    public function returnItem()
    {
        return $this->hasMany('BillReship', 'sub_order_id', 'id');
    }

    /**
     * 删除订单
     * @param $order_ids
     * @param $user_id
     * @return int
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function del($order_ids, $user_id)
    {
        $where[] = ['id', 'in', $order_ids];
        $where[] = ['user_id', 'eq', $user_id];

        $result = $this->where($where)->delete();
        return $result;
    }

    /**
     * 确认签收
     * @param $order_id
     * @param bool $user_id
     * @return mixed
     */
    public function confirm($order_id, $user_id = false)
    {
        $result = [
            'status' => false,
            'data' => [],
            'msg' => ''
        ];
        $where[] = ['id', 'eq', $order_id];
        $where[] = ['pay_status', 'neq', self::PAY_STATUS_NO];
        $where[] = ['ship_status', 'neq', self::SHIP_STATUS_NO];
        $where[] = ['status', 'eq', self::ORDER_STATUS_NORMAL];
        $where[] = ['confirm', 'neq', self::CONFIRM_RECEIPT];
        if ($user_id) {
            $where[] = ['user_id', 'eq', $user_id];
        }
        $data['confirm'] = self::CONFIRM_RECEIPT;
        $data['confirm_time'] = time();

        Db::startTrans();
        try {
            //修改订单
            $re = $this->save($data, $where);
            if(!$re){
                $result['msg'] = "确认收货失败";
            }
            //订单记录
            $orderLog = new OrderLog();
            $orderLog->addLog($order_id, $user_id, $orderLog::LOG_TYPE_SIGN, "确认收货成功", $where);
            $result['status'] = true;
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }
    /**
     * 取消订单操作
     * @param $id
     * @param bool $user_id
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function cancel($id, $user_id = false)
    {
        unset($where);
        $where[] = ['id', 'in', $id];
        $where[] = ['pay_status', 'eq', self::PAY_STATUS_NO];
        $where[] = ['status', 'eq', self::ORDER_STATUS_NORMAL];
        $where[] = ['ship_status', 'eq', self::SHIP_STATUS_NO];
        $msg = '后台订单取消操作';
        if ($user_id) {
            $where[] = ['user_id', 'eq', $user_id];
            $msg = '订单取消操作';
        }
        unset($order_info);
        $order_info = $this->with('orders')->where($where)->select();
        unset($result);
        if ($order_info) {
            Db::startTrans();
            try {
                //更改状态和库存
                unset($order_ids);
                $order_ids = [];
                $orderLog = new OrderLog();
                foreach ($order_info as $k => $v) {
                    $order_ids[] = $v['id'];
                    //订单记录
                    $orderLog->addLog($v['id'], $v['user_id'], $orderLog::LOG_TYPE_CANCEL, $msg, $where);
                    //变更积分
                    if ($v['orders']['point'] > 0) {
                        $pointLogMode = new UserPointLog();
                        unset($res);
                        $res = $pointLogMode->setPoint($v['user_id'], $v['point'], $pointLogMode::POINT_TYPE_ADMIN_EDIT, '取消订单：' . $v['id'] . ' 返还积分');
                        if (!$res['status']) {
                            Db::rollback();
                            return false;
                        }
                    }
                }
                //状态修改
                unset($w);
                unset($d);
                $w[] = ['id', 'in', $order_ids];
                $d['status'] = self::ORDER_STATUS_CANCEL;
                $d['utime'] = time();
                $this->where($w)->update($d);
                #商品列表
                $itemModel = new OrderItems();
                unset($goods);
                $goods = $itemModel->field('product_id,nums')->where('sub_order_id','in',$order_ids)->select();
                #更新库存
                $goodsModel = new Goods();
                foreach ($goods as $v) {
                    $goodsModel->changeStock($v['product_id'], 'cancel', $v['nums']);
                }
                $result = true;
                Db::commit();
                hook('cancelorder',$order_info); // 订单取消的钩子
            } catch (\Exception $e) {
                $result = false;
                Db::rollback();
            }
        } else {
            $result = false;
        }
        return $result;
    }


    /**
     * 判断订单是否可以评价
     * @param $order_id
     * @param $user_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function isOrderComment($order_id, $user_id)
    {
        $where[] = ['id', 'eq', $order_id];
        $where[] = ['user_id', 'eq', $user_id];

        $res = $this->where($where)->find();
        if ($res) {
            if ($res['pay_status'] > self::PAY_STATUS_NO && $res['status'] == self::ORDER_STATUS_NORMAL && $res['ship_status'] > self::SHIP_STATUS_NO && $res['is_comment'] == self::NO_COMMENT) {
                $data = [
                    'status' => true,
                    'msg' => '可以评价',
                    'data' => $res
                ];
            } else {
                $data = [
                    'status' => false,
                    'msg' => '订单状态存在问题，不能评价',
                    'data' => $res
                ];
            }
        } else {
            $data = [
                'status' => false,
                'msg' => '不存在这个订单',
                'data' => $res
            ];
        }
        return $data;
    }

    /**
     * 获取订单不同状态的数量
     * @param $input
     * @return array
     */
    public function getOrderStatusNum($params)
    {
        $ids = explode(",", $params['ids']);
        if ($params['user_id']) {
            $user_id = $params['user_id'];
        } else {
            $user_id = false;
        }
        if ($params['shop_id']) {
            $shop_id = $params['shop_id'];
        } else {
            $shop_id = false;
        }
        $data = [];
        foreach ($ids as $k => $v) {
            $data[$v] = $this->orderCount($v, $user_id,$shop_id);
        }
        #总订单数
        $data['count'] =$this->orderCount(0, $user_id,$shop_id);
        #售后状态查询
        $isAfterSale = $params['isAfterSale'];
        if ($isAfterSale) {
            $model = new BillAftersales();
            $number = $model->getUserAfterSalesNum($user_id, $model::STATUS_WAITAUDIT,$shop_id);
            $data['isAfterSale'] = $number;
        }
        return $data;
    }
    /**
     * 获取订单列表微信小程序
     * @param $input
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getListFromWxApi($params)
    {
        $where = [];
        if (!empty($params['status'])) {
            $where = $this->getReverseStatus($params['status']);
        }
        if (!empty($params['user_id'])) {
            $where[] = ['user_id', 'eq', $params['user_id']];
        }
        if (!empty($params['shop_id'])) {
            $where[] = ['shop_id', 'eq', $params['shop_id']];
        }

        $page = $params['page'] ? $params['page'] : 1;
        $limit = $params['limit'] ? $params['limit'] : 20;

        $data = $this::with(['items','shop'])->where($where)
            ->order('ctime desc')
            ->page($page, $limit)
            ->select();
        $count = $this->where($where)->count();
        return ['data' => $data, 'count' => $count];
    }

    /**
     * 订单数量统计
     * @param int $id
     * @param bool $user_id
     * @return float|string
     */
    protected function orderCount($id = 0, $user_id = false,$shop_id=false)
    {
        $where = [];
        //都需要验证的
        if ($user_id) {
            $where[] = ['user_id', 'eq', $user_id];
        }
        if ($shop_id) {
            $where[] = ['shop_id', 'eq', $shop_id];
        }
        if($id){
            $where = array_merge($where, $this->getReverseStatus($id));
        }

        return $this->where($where)->count();
    }

    /**
     * 获取订单状态反查
     * @param $status
     * @param string $table_name
     * @return array
     */
    protected function getReverseStatus($status, $table_name = '')
    {
        $where = [];
        switch ($status) {
            case self::ALL_PENDING_PAYMENT: //待付款
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_NORMAL],
                    [$table_name . 'pay_status', 'eq', self::PAY_STATUS_NO]
                ];
                break;
            case self::ALL_PENDING_DELIVERY: //待发货
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_NORMAL],
                    [$table_name . 'pay_status', 'eq', self::PAY_STATUS_YES],
                    [$table_name . 'ship_status', 'in', self::SHIP_STATUS_NO . ',' . self::SHIP_STATUS_PARTIAL_YES]
                ];
                break;
            case self::ALL_PENDING_RECEIPT: //待收货
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_NORMAL],
                    [$table_name . 'ship_status', 'eq', self::SHIP_STATUS_YES],
                    [$table_name . 'confirm', 'eq', self::RECEIPT_NOT_CONFIRMED]
                ];
                break;
            case self::ALL_PENDING_EVALUATE: //待评价
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_NORMAL],
                    [$table_name . 'pay_status', '>', self::PAY_STATUS_NO],
                    [$table_name . 'ship_status', 'eq', self::SHIP_STATUS_YES],
                    [$table_name . 'confirm', 'eq', self::CONFIRM_RECEIPT],
                    [$table_name . 'is_comment', 'eq', self::NO_COMMENT]
                ];
                break;
            case self::ALL_COMPLETED_EVALUATE: //已评价
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_NORMAL],
                    [$table_name . 'pay_status', '>', self::PAY_STATUS_NO],
                    [$table_name . 'ship_status', 'eq', self::SHIP_STATUS_YES],
                    [$table_name . 'confirm', 'eq', self::CONFIRM_RECEIPT],
                    [$table_name . 'is_comment', 'eq', self::ALREADY_COMMENT]
                ];
                break;
            case self::ALL_CANCEL: //已取消
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_CANCEL]
                ];
                break;
            case self::ALL_COMPLETED: //已完成
                $where = [
                    [$table_name . 'status', 'eq', self::ORDER_STATUS_COMPLETE]
                ];
                break;
            default:
                break;
        }

        return $where;
    }
    /**
     * 获取订单信息
     * @param $id
     * @param $user_id
     * @param bool $logistics
     * @return bool|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getOrderInfoByOrderID($id, $user_id=false,$logistics = true)
    {
        $order_info = $this->get($id); //订单信息
        if (!$order_info) {
            return false;
        }
        if ($user_id) {
            if ($user_id != $order_info['user_id']) {
                return false;
            }
        }
        $order_info->shop;//店铺信息
        $order_info->orders;//主订单详情
        $order_info->items; //订单详情
        $order_info->user; //用户信息
        $order_info->paymentRelItem; //支付单
        $order_info->refundItem; //退款单
        $order_info->ladingItem; //提货单
        $order_info->returnItem; //退货单
        $order_info->aftersalesItem; //售后单
        //发货单
        $billDeliveryModel = new BillDelivery();
        $deliveryResult = $billDeliveryModel->getDeliveryList($id);
        $order_info['delivery'] = $deliveryResult['data'];

        //获取提货门店
        $order_info['store'] = false;
        if ($order_info['store_id'] != 0) {
            $storeModel = new Store();
            $storeInfo = $storeModel->get($order_info['store_id']);
            $storeInfo['all_address'] = get_area($storeInfo['area_id']) . $storeInfo['address'];
            $order_info['store'] = $storeInfo;
        }
        foreach ($order_info['delivery'] as &$v) {
            $v['logi_name'] = get_logi_info($v['logi_code'], 'logi_name');
        }
        $order_info->hidden(['user' => ['isdel', 'password']]);

        if ($order_info['logistics_id']) {
            $w[] = ['id', 'eq', $order_info['logistics_id']];
            $shipModel = new ShopExpress();
            $order_info['logistics'] = $shipModel->where($w)->find();
        } else {
            $order_info['logistics'] = null;
        }
        $order_info['text_status'] = $this->getStatus($order_info['status'], $order_info['pay_status'], $order_info['ship_status'], $order_info['confirm'], $order_info['is_comment']);
        $order_info['orders']['ship_area_name'] = get_area($order_info['orders']['ship_area_id']);

        if (isset(config('params.payment_type')[$order_info['orders']['payment_code']])) {
            $payment_name = config('params.payment_type')[$order_info['orders']['payment_code']];
        } else {
            $payment_name = false;
        }

        $order_info['orders']['payment_name'] = $payment_name ? $payment_name : '未知支付方式';
        $order_info['orders']['payment_time'] = date('Y-m-d H:i:s',$order_info['orders']['payment_time']);
        //如果有优惠券，数据处理
        if ($order_info['coupon']) {
            $order_info['coupon'] = json_decode($order_info['coupon'], true);
        }

        //获取该状态截止时间
        switch ($order_info['text_status']) {
            case self::ALL_PENDING_PAYMENT: //待付款
                $cancel = getSetting('order_cancel_time') * 86400;
                $ctime = $order_info['ctime'];
                $remaining = $ctime + $cancel - time();
                $order_info['remaining'] = $this->dateTimeTransformation($remaining);
                $order_info['remaining_time'] = $remaining;
                break;
            case self::ALL_PENDING_RECEIPT: //待收货
                $sign = getSetting('order_autoSign_time') * 86400;
                $utime = $order_info['utime'];
                $remaining = $utime + $sign - time();
                $order_info['remaining'] = $this->dateTimeTransformation($remaining);
                $order_info['remaining_time'] = $remaining;
                break;
            case self::ALL_PENDING_EVALUATE: //待评价
                $eval = getSetting('order_autoEval_time') * 86400;
                $confirm = $order_info['confirm_time'];
                $remaining = $confirm + $eval - time();
                $order_info['remaining'] = $this->dateTimeTransformation($remaining);
                $order_info['remaining_time'] = $remaining;
                break;
            default:
                $order_info['remaining'] = false;
                $order_info['remaining_time'] = false;
                break;
        }
        //支付单
        if (count($order_info['paymentRelItem']) > 0) {
            $billPaymentsModel = new BillPayments();
            foreach ($order_info['paymentRelItem'] as &$v) {
                $v['bill'] = $billPaymentsModel->get($v['payment_id']);
                $v['bill']['payment_code_name'] = config('params.payment_type')[$v['bill']['payment_code']];
                $v['bill']['status_name'] = config('params.bill_payments')['status'][$v['bill']['status']];
                $v['bill']['utime_name'] = getTime($v['bill']['utime']);
            }
        }

        //退款单
        if (count($order_info['refundItem']) > 0) {
            foreach ($order_info['refundItem'] as &$v) {
                $v['payment_code_name'] = config('params.payment_type')[$v['payment_code']];
                $v['status_name'] = config('params.bill_refund')['status'][$v['status']];
                $v['ctime_name'] = getTime($v['ctime']);
            }
        }

        //发货单
        if (count($order_info['delivery']) > 0) {
            $logiModel = new Logistics();
            $areaModel = new Area();
            foreach ($order_info['delivery'] as &$v) {
                $v['logi_code_name'] = $logiModel->getNameByCode($v['logi_code']);
                $v['ship_area_id_name'] = $areaModel->getAllName($v['ship_area_id']);
            }
        }

        //提货单
        if (count($order_info['ladingItem']) > 0) {
            $storeModel = new Store();
            $clerkModel = new Clerk();
            $billLadingModel = new BillLading();
            foreach ($order_info['ladingItem'] as &$v) {
                $v['store_id_name'] = $storeModel->getStoreName($v['store_id']);
                $v['status_name'] = config('params.bill_lading')['status'][$v['status']];
                if ($v['status'] == $billLadingModel::STATUS_YES) {
                    $v['utime_name'] = getTime($v['utime']);
                } else {
                    $v['utime_name'] = '';
                }

                if ($v['clerk_id']) {
                    $v['clerk_id_name'] = $clerkModel->getClerkName($v['clerk_id']);
                } else {
                    $v['clerk_id_name'] = '';
                }
            }
        }

        //退货单
        if (count($order_info['returnItem']) > 0) {
            $logiModel = new Logistics();
            foreach ($order_info['returnItem'] as &$v) {
                $v['logi_code_name'] = $logiModel->getNameByCode($v['logi_code']);
                $v['status_name'] = config('params.bill_reship')['status'][$v['status']];
                $v['utime_name'] = getTime($v['utime']);
            }
        }

        //售后单取当前活动的收货单
        $order_info['bill_aftersales_id'] = false;
        if (count($order_info['aftersalesItem']) > 0) {
            $billAftersalesModel = new BillAftersales();
            foreach ($order_info['aftersalesItem'] as $v) {
                $order_info['bill_aftersales_id'] = $v['aftersales_id'];
                //如果售后单里面有待审核的活动售后单，那就直接拿这条
                if ($v['status'] == $billAftersalesModel::STATUS_WAITAUDIT) {
                    break;
                }
            }
        }
        //把退款金额和退货商品查出来
        $this->aftersalesVal($order_info);
        //促销信息
        if ($order_info['promotion_list']) {
            $order_info['promotion_list'] = json_decode($order_info['promotion_list'], true);
        }
        //发票信息
        $invoiceModel = new Invoice();
        $invoiceInfo = $invoiceModel->getOrderInvoiceInfo($order_info['order_id']);
        if ($invoiceInfo['status']) {
            $order_info['invoice'] = $invoiceInfo['data'];
        } else {
            $order_info['invoice'] = [
                'type' => $order_info['orders']['tax_type'],
                'title' => $order_info['orders']['tax_title'],
                'tax_number' => $order_info['orders']['tax_code'],
            ];
        }

        return $order_info;
    }


    /**
     * 获取状态
     * @param $status
     * @param $pay_status
     * @param $ship_status
     * @param $confirm
     * @param $is_comment
     * @return int
     */
    protected function getStatus($status, $pay_status, $ship_status, $confirm, $is_comment)
    {
        if ($status == self::ORDER_STATUS_NORMAL && $pay_status == self::PAY_STATUS_NO) {
            //待付款
            return self::ALL_PENDING_PAYMENT;
        } elseif ($status == self::ORDER_STATUS_NORMAL && $pay_status == self::PAY_STATUS_YES && $ship_status == self::SHIP_STATUS_NO) {
            //待发货
            return self::ALL_PENDING_DELIVERY;
        } else if ($status == self::ORDER_STATUS_NORMAL && $pay_status == self::PAY_STATUS_YES && $ship_status == self::SHIP_STATUS_PARTIAL_YES) {
            //部分发货
            return self::ALL_PARTIAL_DELIVERY;
        } elseif ($status == self::ORDER_STATUS_NORMAL && $ship_status == self::SHIP_STATUS_YES && $confirm == self::RECEIPT_NOT_CONFIRMED) {
            //待收货
            return self::ALL_PENDING_RECEIPT;
        } elseif ($status == self::ORDER_STATUS_NORMAL && $pay_status > self::PAY_STATUS_NO && $ship_status == self::SHIP_STATUS_YES && $confirm == self::CONFIRM_RECEIPT && $is_comment == self::NO_COMMENT) {
            //待评价
            return self::ALL_PENDING_EVALUATE;
        } elseif ($status == self::ORDER_STATUS_NORMAL && $pay_status > self::PAY_STATUS_NO && $ship_status == self::SHIP_STATUS_YES && $confirm == self::CONFIRM_RECEIPT && $is_comment == self::ALREADY_COMMENT) {
            //已评价
            return self::ALL_COMPLETED_EVALUATE;
        } elseif ($status == self::ORDER_STATUS_COMPLETE) {
            //已完成
            return self::ALL_COMPLETED;
        } elseif ($status == self::ORDER_STATUS_CANCEL) {
            //已取消
            return self::ALL_CANCEL;
        }
    }

    /**
     * 发货改状态
     * @param $order_id
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function ship($order_id, $item)
    {
        $where[] = ['id', 'eq', $order_id];
        $where[] = ['status', 'eq', self::ORDER_STATUS_NORMAL];
        $where[] = ['ship_status', 'IN', [self::SHIP_STATUS_NO, self::SHIP_STATUS_PARTIAL_NO, self::SHIP_STATUS_PARTIAL_YES]];        //未发货，部分发货，部分退货状态(怕部分发货中的部分退货这种业务场景，所以加这个字段)
        $info = $this->where($where)->find();
        if (!$info) {
            return error_code(10000);
        }
        //更新订单明细发货数量，并校验是否发完
        $orderItemsModel = new OrderItems();
        $isOver = $orderItemsModel->ship($order_id, $item);
        if ($isOver) {
            $info->ship_status = self::SHIP_STATUS_YES;
        } else {
            $info->ship_status = self::SHIP_STATUS_PARTIAL_YES;
        }
        $info->save();
        return [
            'status' => true,
            'data' => '',
            'msg' => ''
        ];
    }

    /**
     * 构建需要发货的数据，和发货单密切关联
     * @param $id
     * @param $shop_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getOrderShipInfo($ids,$shop_id)
    {
        $return = [
            'status' => true,
            'msg' => '',
            'data' => []
        ];
        $where[] =['shop_id','=',$shop_id];
        $where[] = ['id', 'in', $ids];

        $order = $this->with(['items','orders'])
            ->field('id,order_id,user_id,pay_status,ship_status,status,logistics_id,logistics_name,cost_freight,ship_area_id,ship_address,ship_name,ship_mobile,weight,mark,store_id')
            ->where($where)
            ->select();
        if ($order->isEmpty()) {
            $return['status'] = false;
            $return['msg'] = "请选择订单";
            return $return;
        }
        $order = $order->toArray();

        $store_id = false;          //校验是普通快递收货，还是门店自提，这两种收货方式不能混着发
        foreach ($order as $k => $v) {
            if ($v['status'] != self::ORDER_STATUS_NORMAL) {
                $return['status'] = false;
                $return['msg'] .= '订单号：' . $v['id'] . ' 非正常状态不能发货。<br />';
            } elseif ($v['pay_status'] == self::PAY_STATUS_NO) {
                $return['status'] = false;
                $return['msg'] .= '订单号：' . $v['id'] . ' 未支付不能发货。<br />';
            } elseif (!in_array($v['ship_status'], [self::SHIP_STATUS_NO, self::SHIP_STATUS_PARTIAL_YES])) {
                $return['status'] = false;
                $return['msg'] .= '订单号：' . $v['id'] . ' 不是待发货和部分发货状态不能发货。<br />';
            }
            //校验，不能普通快递和门店自提，不能混发
            if($store_id !== false){
                if($store_id != $v['store_id']){
                    $return['status'] = false;
                    $return['msg'] = '门店自提订单和普通订单不能混合发货。';
                    return $return;
                }
            }else{
                $store_id = $v['store_id'];
            }
            $this->aftersalesVal($order[$k]); //获取售后数量
        }
        if (!$return['status']) {
            return $return;
        }
        //------------------------------------------------
        $msg_arr = [
            'user_id' => true,
            'ship_info' => true
        ];
        $newOrder = [
            'order_id' => $ids,
            'weight' => 0,
            'memo' => [],
            'cost_freight' => 0,
            'store_id' => 0,
            'ship_area_id' => $order[0]['orders']['ship_area_id'],
            'ship_address' => $order[0]['orders']['ship_address'],
            'ship_name' => $order[0]['orders']['ship_name'],
            'ship_mobile' => $order[0]['orders']['ship_mobile'],
            'logistics_id' => $order['logistics_id'],
            'items' => [],
            'orders' => $order                                  //把订单信息冗余上去
        ];

        foreach ($order as $v) {
            //组合总重量
            $newOrder['weight'] = $newOrder['weight'] + $v['weight'];
            $newOrder['cost_freight'] = $newOrder['cost_freight'] + $v['cost_freight'];
            //组合备注信息
            if ($v['memo'] && $v['memo'] != '') {
                $newOrder['memo'][$v['order_id']] = $v['memo'];
            }
            //组合明细
            //$this->aftersalesVal($v); //获取售后数量,在上面怼

            foreach ($v['items'] as $vv) {
                if (!isset($newOrder['items'][$vv['product_id']])) {
                    $newOrder['items'][$vv['product_id']] = $vv;
                } else {
                    $newOrder['items'][$vv['product_id']]['product_id']=$vv['product_id'];
                    $newOrder['items'][$vv['product_id']]['goods_id']=$vv['goods_id'];
                    $newOrder['items'][$vv['product_id']]['bn']=$vv['bn'];
                    $newOrder['items'][$vv['product_id']]['sn']=$vv['sn'];
                    $newOrder['items'][$vv['product_id']]['name']=$vv['name'];
                    $newOrder['items'][$vv['product_id']]['addon']=$vv['addon'];

                    $newOrder['items'][$vv['product_id']]['nums'] = $newOrder['items'][$vv['product_id']]['nums'] + $vv['nums']; //总数量
                    $newOrder['items'][$vv['product_id']]['weight'] = $newOrder['items'][$vv['product_id']]['weight'] + $vv['weight']; //总重量
                    $newOrder['items'][$vv['product_id']]['sendnums'] = $newOrder['items'][$vv['product_id']]['sendnums'] + $vv['sendnums']; //已发送数量
                    $newOrder['items'][$vv['product_id']]['reship_nums'] = $newOrder['items'][$vv['product_id']]['reship_nums'] + $vv['reship_nums']; //退货数量
                }
            }
            //判断是否有多个用户的订单
            if ($msg_arr['user_id']) {
                if ($msg_arr['user_id'] === true) {
                    $msg_arr['user_id'] = $v['user_id'];
                } else {
                    if ($msg_arr['user_id'] != $v['user_id']) {
                        $msg_arr['user_id'] = false;
                    }
                }
            }

            //判断是否是多个收货地址
            if ($msg_arr['ship_info']) {
                if ($msg_arr['ship_info'] === true) {
                    $msg_arr['ship_info'] = $v['orders']['ship_area_id'] . $v['orders']['ship_address'];
                } else {
                    if ($msg_arr['ship_info'] != $v['orders']['ship_area_id'] . $v['orders']['ship_address']) {
                        $msg_arr['ship_info'] = false;
                    }
                }
            }
        }

        //判断用户
        if (!$msg_arr['user_id']) {
            $return['msg'] .= '多个用户订单，';
        }
        //判断多个收货地址
        if (!$msg_arr['ship_info']) {
            $return['msg'] .= '多个收货地址，';
        }
        //是否有警告
        if ($return['msg'] != '') {
            $return['msg'] = rtrim($return['msg'], '，');
            $return['msg'] = '请注意！合并发货订单中存在：' . $return['msg'] . '。确定发货吗？';
        }
        $return['data'] = $newOrder;
        return $return;
    }

    /**
     * 把退款的金额和退货的商品数量保存起来
     * @param $orderInfo
     * @return bool
     */
    public function aftersalesVal(&$orderInfo)
    {
        $add_aftersales_status = false;     //是否可以提交售后,只要没退完就可以进行售后
        $billAftersalesModel = new BillAftersales();
        $re = $billAftersalesModel->orderToAftersales($orderInfo['id']);
        //已经退过款的金额
        $orderInfo['refunded'] = $re['data']['refund_money'];
        //算退货商品数量
        foreach ($orderInfo['items'] as $k => $v) {
            if (isset($re['data']['reship_goods'][$v['id']])) {
                $orderInfo['items'][$k]['reship_nums'] = $re['data']['reship_goods'][$v['id']];

                if(!$add_aftersales_status && $orderInfo['items'][$k]['nums'] > $orderInfo['items'][$k]['reship_nums']){            //如果没退完，就可以再次发起售后
                    $add_aftersales_status = true;
                }
            } else {
                $orderInfo['items'][$k]['reship_nums'] = 0;

                if(!$add_aftersales_status){            //没退货，就能发起售后
                    $add_aftersales_status = true;
                }
            }
        }
        //商品没退完或没退，可以发起售后，但是订单状态不对的话，也不能发起售后
        if($orderInfo['pay_status'] == self::PAY_STATUS_NO || $orderInfo['status'] != self::ORDER_STATUS_NORMAL){
            $add_aftersales_status = false;
        }
        //商品确认收货后就不可以发起售后
        if($orderInfo['confirm'] == self::CONFIRM_RECEIPT || $orderInfo['status'] != self::ORDER_STATUS_NORMAL){
            $add_aftersales_status = false;
        }
        $orderInfo['add_aftersales_status'] = $add_aftersales_status;


        return true;
    }


    /**
     * 时间转换
     * @param $time
     * @return string
     */
    protected function dateTimeTransformation($time)
    {
        $newtime = '';
        $d = floor($time / (3600 * 24));
        $h = floor(($time % (3600 * 24)) / 3600);
        $m = floor((($time % (3600 * 24)) % 3600) / 60);
        $s = floor((($time % (3600 * 24)) % 3600) % 60);
        $s = ($s < 10) ? '0' . $s : $s;
        if ($d > '0') {
            $newtime = $d . '天' . $h . '小时' . $m . '分' . $s . '秒';
        } else {
            if ($h != '0') {
                $newtime = $h . '小时' . $m . '分' . $s . '秒';
            } else {
                $newtime = $m . '分' . $s . '秒';
            }
        }
        return $newtime;
    }

}